package com.nekocode.http;

import android.content.Context;

import com.nekocode.utils.FileManager;

import java.io.File;
import java.util.concurrent.Callable;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.FutureTask;

/**
 * User: qii
 * Date: 14-6-10
 */
public class DownloadFutureTask extends FutureTask<Boolean> {

    public static DownloadFutureTask newInstance(Context context, String url) {
        JobCallable jobCallable = new JobCallable(context, url);
        DownloadFutureTask downloadFutureTask = new DownloadFutureTask(jobCallable);
        jobCallable.futureTask = downloadFutureTask;
        return downloadFutureTask;
    }

    private JobCallable callable;
    static volatile boolean pauseDownloadWork = false;
    static final Object pauseDownloadWorkLock = new Object();

    public static void setPauseDownloadWork(boolean pauseWork) {
        synchronized (pauseDownloadWorkLock) {
            pauseDownloadWork = pauseWork;
            if (!pauseDownloadWork) {
                pauseDownloadWorkLock.notifyAll();
            }
        }
    }

    private DownloadFutureTask(JobCallable callable) {
        super(callable);
        this.callable = callable;
    }

    public void addDownloadListener(FileDownloaderHttpHelper.DownloadListener listener) {
        callable.addDownloadListener(listener);
    }

    public String getUrl() {
        return callable.url;
    }

    private static class JobCallable implements Callable<Boolean> {

        private DownloadFutureTask futureTask;

        private CopyOnWriteArrayList<FileDownloaderHttpHelper.DownloadListener> downloadListenerList
                = new CopyOnWriteArrayList<FileDownloaderHttpHelper.DownloadListener>();

        private String url;
        private Context context;

        private int progress;

        private int max;

        public void addDownloadListener(FileDownloaderHttpHelper.DownloadListener listener) {
            if (listener == null) {
                return;
            }
            downloadListenerList.addIfAbsent(listener);
            if (progress > 0 && max > 0) {
                listener.pushProgress(progress, max);
            }
        }

        private JobCallable(Context context, String url) {
            this.url = url;
            this.context = context;
        }

        @Override
        public Boolean call() throws Exception {
            synchronized (pauseDownloadWorkLock) {
                while (pauseDownloadWork && !Thread.currentThread()
                        .isInterrupted()) {
                    try {
                        pauseDownloadWorkLock.wait();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
            }
            String filePath = FileManager.generateDownloadFileName(context, url);

            String actualDownloadUrl = url;

            boolean result = false;
            for (int i = 0; i < 3; i++) {
                result = HttpUtility.getInstance().executeDownloadTask(context, actualDownloadUrl, filePath,
                        new FileDownloaderHttpHelper.DownloadListener() {
                            @Override
                            public void pushProgress(int progress, int max) {
                                JobCallable.this.progress = progress;
                                JobCallable.this.max = max;
                                for (FileDownloaderHttpHelper.DownloadListener downloadListener : downloadListenerList) {
                                    if (downloadListener != null) {
                                        downloadListener.pushProgress(progress, max);
                                    }
                                }
                            }
                        });

                if(result) {
                    //TODO:add to db
//                    DownloadPicturesDBTask.add(this.url,
//                            FileManager.generateDownloadFileName(this.url),
//                            this.method);
                    break;
                } else {
                    new File(actualDownloadUrl).delete();
                }
            }

            TaskCache.removeDownloadTask(url, futureTask);
            return result;
        }
    }

}
